#!/bin/bash
root_dir="/usr/local/edata"
role=$1
mode=$(cat mode)
echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting $role in $mode mode"
function start_journalnode(){
    hdfs --daemon start journalnode
    if [ $? -eq 0 ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting journalnode success"
    else
        echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting journalnode fail"
    fi
}

function start_namenode(){
    if [ $mode == "ha" ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking zookeeper cluster..."
        while IFS= read -r line
        do
            if [[ $line == *"ha.zookeeper.quorum"* ]];then
                IFS="=" read -r name value <<< $line
                IFS="," read -r -a zk_cluster <<< $value
                for zk_node in "${zk_cluster[@]}";do
                    IFS=":" read -r ip port <<< $zk_node
                    wait_for_service zk_node $ip $port
                done
            fi
        done < "hadoop_$mode.env"
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking $root_dir/hadoop/hdfs/journal..."
        if [ -z "$(ls -A $root_dir/hadoop/hdfs/journal)" ];then
            echo "$(date +"%Y-%m-%d %H:%M:%S") WARNING $root_dir/hadoop/hdfs/journal is empty,formatting..."
            echo "Y" | hdfs namenode -format
            if [ $? -eq 0 ];then
                echo "$(date +"%Y-%m-%d %H:%M:%S") INFO formatting namenode success"
            else
                echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR formatting namenode fail"
            fi
        else
            echo "$(date +"%Y-%m-%d %H:%M:%S") INFO $root_dir/hadoop/hdfs/journal is not empty"
        fi
        ha_service_state=$(hdfs haadmin -getAllServiceState)
        if [[ $ha_service_state == *"active"* ]] || [[  $ha_service_state == *"standby"*  ]];then
            echo "$(date +"%Y-%m-%d %H:%M:%S") INFO an namenode exist,initialize metadata for another namenode"
            hdfs namenode -bootstrapStandby
            if [ $? -eq 0 ];then
                echo "$(date +"%Y-%m-%d %H:%M:%S") INFO bootstrapping metadata success"
            else
                echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR bootstrapping metadata fail"
            fi
        
        fi
    fi

    if [ $mode == "sa" ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking $root_dir/hadoop/hdfs/name..."
        if [ -z "$(ls -A $root_dir/hadoop/hdfs/name)" ];then
            echo "$(date +"%Y-%m-%d %H:%M:%S") WARNING namenode name dir is empty,formatting..."
            echo "Y" | hdfs namenode -format
            if [ $? -eq 0 ];then
                echo "$(date +"%Y-%m-%d %H:%M:%S") INFO formatting namenode success"
            else
                echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR formatting namenode fail"
            fi
        else
            echo "$(date +"%Y-%m-%d %H:%M:%S") INFO $root_dir/hadoop/hdfs/name is not empty"
        fi
    fi
    hdfs --daemon start namenode
    if [ $? -eq 0 ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting namenode success"
    else
        echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting namenode fail"
    fi
}

function start_zkfc(){
    hdfs --daemon start zkfc
    if [ $? -eq 0 ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting zkfc success"
    else
        echo "$(date +"%Y-%m-%d %H:%M:%S") WARNING starting zkfc fail"
        echo "$(date +"%Y-%m-%d %H:%M:%S") WARNING trying to format znode"
        hdfs zkfc -formatZK -force
        if [ $? -eq 0 ];then
            echo "$(date +"%Y-%m-%d %H:%M:%S") INFO formatting znode success"
            start_zkfc
        else
            echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR formatting znode fail"
            exit 1
        fi
    fi
}

function start_secondarynamenode(){
    if [ $mode == "ha" ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR secondarynamenode only run in sa mode"
        exit 1
    else
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking namenode..."
        while IFS= read -r line
        do
            if [[ $line == *"dfs.namenode.http-address"* ]];then
                IFS="=" read -r prefix suffix <<< $line
                IFS=":" read -r ip port <<< $suffix
                wait_for_service namenode $ip $port
            fi
        done < "hadoop_$mode.env"
        hdfs --daemon start secondarynamenode
        if [ $? -eq 0 ];then
            echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting secondarynamenode success"
        else
            echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting secondarynamenode fail"
        fi
    fi
}

function start_datanode(){
    echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking namenode..."
    if [ $mode == "sa" ];then
        while IFS= read -r line
        do
            if [[ $line == *"dfs.namenode.http-address"* ]];then
                IFS="=" read -r prefix suffix <<< $line
                IFS=":" read -r ip port <<< $suffix
                wait_for_service namenode $ip $port
            fi
        done < "hadoop_$mode.env"
        hdfs --daemon start datanode
        if [ $? -eq 0 ];then
            echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting datanode success"
        else
            echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting datanode fail"
        fi
    fi
    if [ $mode == "ha" ];then
        ha_service_state=$(hdfs haadmin -getAllServiceState)
        if [[ $ha_service_state == *"active"* ]];then
            hdfs --daemon start datanode
            if [ $? -eq 0 ];then
                echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting datanode success"
            else
                echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting datanode fail"
            fi
        else
            echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR no active namenode is available,starting datanode fail"
        fi
    fi
    
}

function start_resourcemanager(){
    if [ $mode == "ha" ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking zookeeper cluster"
        while IFS= read -r line
        do
            if [[ $line == *"hadoop.zk.address"* ]];then
                IFS="=" read -r prefix suffix <<< $line
                IFS="," read -r -a zk_cluster <<< $suffix
                for zk_node in "${zk_cluster[@]}";do
                    IFS=":" read -r ip port <<< $zk_node
                    wait_for_service zk_node $ip $port
                done
            fi
        done < "hadoop_$mode.env"
    fi
    yarn --daemon start resourcemanager
    if [ $? -eq 0 ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting resourcemanager success"
    else
        echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting resourcemanager fail"
    fi
}

function start_nodemanager(){
    echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking resourcemanager..."
    while IFS= read -r line
    do
        if [[ $line == *"resource-tracker.address"* ]];then
            IFS="=" read -r prefix rm_node <<< $line
            IFS=":" read -r ip port <<< $rm_node
            wait_for_service resourcemanager $ip $port
        fi
    done < "hadoop_$mode.env"
    yarn --daemon start nodemanager
    if [ $? -eq 0 ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting nodemanager success"
    else
        echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting nodemanager fail"
    fi
}

function wait_for_service(){
    service=$1
    ip=$2
    port=$3
    max_retry=5
    retry_second=5
    let i=1
    nc -z $ip $port
    result=$?
    while [ $result -ne 0 ]; do
        echo "$(date +"%Y-%m-%d %H:%M:%S") WARNING [$i/$max_retry] $service $ip:$port is not available"
        if [ $i == $max_retry ];then
            echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR [$i/$max_retry] $service $ip:$port is still not available,quitting..."
            exit 1
        fi
        echo "$(date +"%Y-%m-%d %H:%M:%S") WARNING [$i/$max_retry] reconnecting $service $ip:$port in $retry_second seconds"
        let "i++"
        sleep $retry_second
        nc -z $ip $port
        result=$?
    done
    echo "$(date +"%Y-%m-%d %H:%M:%S") INFO [$i/$max_retry] $service $ip:$port is available"
}

if [ $role == "journalnode" ];then
    start_journalnode
fi

if [ $role == "namenode" ];then
    start_namenode
fi

if [ $role == "zkfc" ];then
    start_zkfc
fi

if [ $role == "secondarynamenode" ];then
    start_secondarynamenode
fi

if [ $role == "datanode" ];then
    start_datanode
fi

if [ $role == "resourcemanager" ];then
    start_resourcemanager
fi

if [ $role == "nodemanager" ];then
    start_nodemanager
fi

if [ $role == "all" ];then
    if [ $mode == "ha" ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") WARNING parameter all is only supported in sa mode"
        exit 1
    fi
    start_namenode
    start_secondarynamenode
    start_datanode
    start_resourcemanager
    start_nodemanager
fi
